﻿#region License statement
// NJamb, a specification and delta-specification DSL
// Copyright (c) 2010-2011, Mark Knell
// Published under the MIT License; all other rights reserved
#endregion

#region using...
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using NUnit.Framework;
using Stile.Types.Enumerables;
#endregion

namespace NJamb.DemoCode.Antipatterns
{
    [TestFixture]
    public class SharedSetup
    {
        private const decimal InitialBalance = 10m;
        private Account _testSubject;

        [Test]
        public void Deposit()
        {
            GivenAnAccount();
            WhenDeposit();
            ThenBalanceReflectsDeposit();
            ThenDepositIsLogged();
        }

        [Test]
        public void Withdraw()
        {
            GivenAnAccount();
            WhenWithdrawFifteen();
            ThenBalanceReflectsWithdrawal();
            ThenDepositIsLogged();
        }

        private void GivenAnAccount()
        {
            _testSubject = new Account(InitialBalance);
        }

        private void ThenBalanceReflectsDeposit()
        {
            Assert.That(_testSubject.Balance, Is.EqualTo(20m));
        }

        private void ThenBalanceReflectsWithdrawal()
        {
            Assert.That(_testSubject.Balance, Is.EqualTo(5));
        }

        private void ThenDepositIsLogged()
        {
            Assert.That(_testSubject.GetLog().Any());
        }

        private void WhenDeposit()
        {
            _testSubject.Deposit(InitialBalance);
        }

        private void WhenWithdrawFifteen()
        {
            _testSubject.Withdraw(15m);
        }

        public class Account
        {
            private readonly List<decimal> _adjustments;

            public Account(decimal initialBalance)
            {
                Balance = initialBalance;
                _adjustments = new List<decimal>();
            }

            public decimal Balance { get; private set; }

            public void Deposit(decimal amount)
            {
                _adjustments.Add(amount);
                Balance += amount;
            }

            public ReadOnlyCollection<decimal> GetLog()
            {
                return _adjustments.ToReadOnly();
            }

            public void Withdraw(decimal amount) {}
        }
    }
}
